import { NodeStatus } from "../NodeStatus";
import { ActionNode } from "./ActionNode";


/**
 * 状态类动作节点
 */
export abstract class StatefulActionNode<T> extends ActionNode<T> {


    constructor(name: string,blackboard: T) {
        super(name,blackboard);
    }
    
    Tick(): NodeStatus {
        const initial_status = this.status;
        if (initial_status === NodeStatus.IDLE) {
            const new_status = this.onStart();
            if (new_status === NodeStatus.IDLE) {
                throw new Error('AsyncActionNode2::onStart() must not return IDLE');
            }
            return new_status;
        }

        if (initial_status === NodeStatus.RUNNING) {
            const new_status = this.onRunning();
            if (new_status === NodeStatus.IDLE) {
                throw new Error('AsyncActionNode2::onRunning() must not return IDLE');
            }
            return new_status;
        }
        return initial_status;
    }

    /// method to be called at the beginning.
    /// If it returns RUNNING, this becomes an asychronous node.
    abstract onStart(): NodeStatus;

    /// method invoked by a RUNNING action.
    abstract onRunning(): NodeStatus;

    /// when the method halt() is called and the action is RUNNING, this method is invoked.
    /// This is a convenient place todo a cleanup, if needed.
    abstract onHalted(): void;
}